import os
import random
import string
from PIL import Image,ImageFont,ImageDraw,ImageFilter

class ImageVerify:
    def __init__(self,width=140,height=40,length=4,size=28):
        """
        初始化
        :param width: 图片的宽度
        :param height: 图片的高度
        :param length: 字符长度
        :param size:字体大小
        """
        self.width=width
        self.height=height
        self.length=length
        self.size=size

    def  random_str(self):
        """
        随机字符串
        10个数字26个大小写字母
        :return: 随机字符串
        """
        source = string.ascii_letters + string.digits

        return ''.join(random.sample(source,self.length))

    def random_color(self,start=0 ,end=255):
        """
        随机颜色RGB
        :param start: 起始值
        :param end: 结束值
        :return: tuple(r,g,b)
        """
        res = (random.randint(0,255) for i in range(3))
        return tuple(res)

    def random_lines(self,dram):
        """
        绘制干绕行
        两点决定一条线
        一个点(x,y)决定
        :param dram:画笔对象
        :return:
        """
        for i in range (self.length): # 确定画几条线
            lines = [(random.randint(0,self.width),random.randint(0,self.length)) for i in range(2) ] # 两个点
            # 用画笔将随机两点用fill颜色连成一条2px的线
            dram.line(list(lines),fill=self.random_color(start=100),width=2)


    def random_points(self,dram,rate):
        """
        绘制干扰点
        (x,y)
        :param dram: 画笔对象
        :param rate: 出现频率
        :return:
        """
        for x in range(self.width): # x轴取值
            for y in range(self.height): # y轴取值
                if random.randint(1,100) <=rate: # 控制概率，满足条件才用随机的fill画点
                    dram.point((x,y),fill=self.random_color(start=150))


    def image_code(self):
        """
        生成验证码图片
        :return:
        """
        # 创建画布,画布 , 白色背景图
        image = Image.new('RGB',(self.width,self.height),(255,255,255))

        # 创建Font对象，字体对象
        file = os.path.dirname(os.path.abspath(__file__)) # 当前文件的绝对路径
        font = ImageFont.truetype(f'{file}/HYYakuHei-85W.ttf',self.size)

        # 创建dram对象,画笔
        dram = ImageDraw.Draw(image)

        # 生成随机字符串
        code = self.random_str()

        # 将字符串画上画布
        for t in range(self.length):
            # 将验证码中的每个字符在(30*t,3)坐标处开始，用file颜色，用font字体画出
            dram.text((30*t+20,3),code[t],font=font,fill=self.random_color(end=60))
        # 用画笔画画干扰线
        self.random_lines(dram)

        # 用画笔干扰点
        self.random_points(dram,20)

        # 图形模糊
        image = image.filter(ImageFilter.BLUR)
        return image,code

# if __name__=='__main__':
#     imgVerify = ImageVerify()
#     img =imgVerify.image_code()
#     with open('test.png','wb') as f:
#         img.save(f)
